home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Utilities / Winter Shell 1.0d2 / Source / Libraries / AssertLib / AssertLib.c next >
Encoding:
C/C++ Source or Header  |  1994-01-20  |  4.5 KB  |  141 lines  |  [TEXT/KAHL]

  1. /* Assertion handling and recovery library. Inspired by the language
  2.     Eiffel, by Bertrand Meyer (see the book by him for details). There are
  3.     currently (91/05/25) 3 types of assertion macros: "require", used
  4.     for preconditions; "ensure"; used for postconditions; and "check",
  5.     used for assertions anywhere in the middle of a function. These macros
  6.     can be used in the exact same way as the ANSI standard "assert" macro.
  7.     See the header file for more specific details.
  8.     
  9.     Assertions can be disabled during compilation by defining the ANSI
  10.     standard flag "NDEBUG". Any one of the 3 assertion macros can be
  11.     enabled by defining a corresponding preprocessor flag. If
  12.     assertions are compiled with the code they can be disabled at
  13.     run-time using the appropriately named global variables. You
  14.     can print a trace of all assertions called by compiling with
  15.     ASSERT_TRACE and setting the trace flag in the assert options
  16.     global variable.
  17.     
  18.     The default action when an assertion fails depends on the release level
  19.     (see intialization of _assert structure below). An assertion may trigger
  20.     an exception when it fails. By triggering an exception, assertions can
  21.     be treated in a manner similar to any other error, resulting in at least
  22.     somewhat failure tolerant code. By setting the options correctly, you
  23.     can also allow the application to continue, which may be useful during
  24.     debugging, since it allows you to examine the conditions in the routine
  25.     that caused the assertion to fail.
  26.     
  27.     Compiling with assertions can greatly increase the number of
  28.     strings in the program. In THINK C, it may be necessary to use the
  29.     far data option. If this still results in more strings than
  30.     acceptable, you can define ASSERT_COMPACT which prevents display
  31.     of the condition string.
  32.     
  33.     Revision History:
  34.     
  35.     94/01/20 aih
  36.     - updated a few comments
  37.     
  38.     94/01/06 aih
  39.     - uses debug library to print error messages
  40.     
  41.     93/12/15 aih
  42.     - added ASSERT_COMPACT and ASSERT_FNAME to save string space
  43.     
  44.     93/10/26 aih
  45.     - the number of assertion options was getting large so i put them
  46.     all into a global structure
  47.     - added an option to print the stack frame on failure (not implemented yet)
  48.     
  49.     93/10/18 aih
  50.     - updated and added some comments from an older version of this library
  51.     - added exception generation on assertion failure
  52.     
  53.     93/03/15 aih
  54.     - simplified library
  55.     
  56.     93/03/12 AIH
  57.     - System error alert isn't displayed since that caused a crash sometimes
  58.     
  59.     91/06/13 AIH
  60.     - Fixed a grammatical mistake in the comments and added a few comments
  61.     
  62.     91/05/25 AIH
  63.     - Fixed a few mistakes in the comments and added a few comments
  64.     
  65.     91/05/12 AIH
  66.     - Assertions are also echoed to a file
  67.     
  68.     91/05/06 AIH
  69.     - Added ability to do a long jump after an assertion is violated
  70.     
  71.     91/04/20 AIH
  72.     - The trailing newline is removed when DebugStr is called
  73.     
  74.     91/03/18 AIH
  75.     - Added separate compile-time and run-time flags for disabling
  76.     each level of assertions.
  77.     - Added some comments
  78.     - Made error string static so it won't use much stack space
  79.     
  80.     91/01/11 AIH
  81.     - Merged AssertLibA4 into this file
  82.     
  83.     91/01/05 Ari Halberstadt (AIH)
  84.     - Inserted this standard header in all files */
  85.  
  86. #ifndef NDEBUG
  87.  
  88. #include <string.h>
  89. #include <stdio.h>
  90. #include "pstr.h"
  91. #include "AssertLib.h"
  92. #include "DebugLib.h"
  93. #include "ExceptionLib.h"
  94. #include "MacLib.h"
  95.  
  96. struct _assert_options _assert = {
  97.     RELEASE_LEVEL != RELEASE_FINAL,        /* require */
  98.     RELEASE_LEVEL != RELEASE_FINAL,        /* ensure */
  99.     RELEASE_LEVEL != RELEASE_FINAL,        /* check */
  100.     RELEASE_LEVEL == RELEASE_DEV,            /* debug */
  101.     RELEASE_LEVEL != RELEASE_DEV,            /* raise */
  102.     false,                                        /* print */
  103.     false,                                        /* stack */
  104.     false,                                        /* trace */
  105. };
  106.  
  107. static const char *what[ASSERT_LAST_KIND] = { "Require", "Ensure", "Check" };
  108.  
  109. /* function called to trace an assertion */
  110. int _assert_trace(int type, const char *expr, const char *file, long line)
  111. {
  112.     if (expr)
  113.         DebugPrintf("%s: %s, file %s, line %ld\n", what[type], expr, file, line);
  114.     else
  115.         DebugPrintf("%s: file %s, line %ld\n", what[type], file, line);
  116. }
  117.  
  118. /* function called when an assertion fails */
  119. int _assert_failed(int type, const char *expr, const char *file, long line)
  120. {
  121.     CStr255 msg;
  122.     Str255 pmsg;
  123.     
  124.     /* program_note: _assert.stack not implemented yet */
  125.     if (expr)
  126.         sprintf(msg, "%s failed: %s, file %s, line %ld", what[type], expr, file, line);
  127.     else
  128.         sprintf(msg, "%s failed: file %s, line %ld", what[type], file, line);
  129.     if (_assert.debug && MacHasDebugger())
  130.         DebugStr(c2pstrcpy(pmsg, msg));
  131.     if (_assert.print)
  132.         DebugPrintf("%s\n", msg);
  133.     if (_assert.raise) {
  134.         FailExplanationSet(msg);
  135.         RAISE;
  136.     }
  137.     return(0);
  138. }
  139.  
  140. #endif /* NDEBUG */
  141.